﻿using System;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace Docsbox.MTFExporter
{
    /// <summary>
    /// This webpart is used to export Monthly MTF Account information to a Csv file.
    /// to use this webpart, create a view in the MTF Account list, and add this webpart to the view page.
    /// </summary>
    [ToolboxItemAttribute(false)]
    public class MTFExporter : WebPart
    {
        private Button btnExport = null;

        private Literal startDateLabel = null;
        private Literal endDateLabel = null;
        private TextBox startDate = null;
        private TextBox endDate = null;
        private Literal Message = null;


        private const string jQueryScriptKey = "jquery";
        private const string jQueryUIScriptKey = "jqueryui";
        private const string jQueryCustomScriptKey = "calendarcustom";

        public MTFExporter()
        {
            this.PreRender += new EventHandler(MTFExporter_PreRender);
        }

        void MTFExporter_PreRender(object sender, EventArgs e)
        {

            ClientScriptManager csm = Page.ClientScript;
            using(SPSite site = new SPSite(SPContext.Current.Site.ID))
            {
                string siteUrl = site.Url;
                if (!siteUrl.EndsWith("/"))
                    siteUrl += "/";

                if(!csm.IsClientScriptIncludeRegistered("jqueryScript"))
                    csm.RegisterClientScriptInclude("jqueryScript",siteUrl + "_layouts/VehicleFinance/jquery-latest.js");

                if (!csm.IsClientScriptIncludeRegistered("jqueryUIScript"))
                    csm.RegisterClientScriptInclude("jqueryUIScript", siteUrl + "_layouts/VehicleFinance/jquery-ui.js");

                if (!csm.IsClientScriptIncludeRegistered("jQueryDateTimeBinderScript"))
                    csm.RegisterClientScriptInclude("jQueryDateTimeBinderScript", siteUrl + "_layouts/VehicleFinance/custom-datetime.js");
                Page.Header.Controls.Add(new LiteralControl("<Link rel=\"stylesheet\" type=\"text/css\" href=\"" + siteUrl + "_layouts/VehicleFinance/jquery-ui.css\" />"));
            }

        }

        protected override void CreateChildControls()
        {
            Controls.Clear();
            if(ValidateWeb())
            {
                startDateLabel = new Literal {Text = "Start Date: "};
                this.Controls.Add(startDateLabel);

                startDate = new TextBox {ID = "DateStartTextBox", Width = 128};
                this.Controls.Add(startDate);

                endDateLabel = new Literal {Text = "End Date: "};
                this.Controls.Add(endDateLabel);

                endDate = new TextBox {ID = "DateEndTextBox", Width = 128};
                this.Controls.Add(endDate);

                btnExport = new Button {ID = "btnExport", Text = "Export", ToolTip = "Export Account data"};
                btnExport.Click +=new EventHandler(btnExport_Click);
                btnExport.OnClientClick = "_spFormOnSubmitCalled=false;";
                this.Controls.Add(btnExport);

                Message = new Literal() {ID = "lblMessage", Text=""};
                Controls.Add(Message);

            }
            else
            {
                throw new Exception("Can't find Account List in this web. Please verfiy the web is loaded correctly.");
            }
            base.CreateChildControls();

        }

        void btnExport_Click(object sender, EventArgs e)
        {
            Message.Text = "";
            string start = startDate.Text.Trim();
            string end = endDate.Text.Trim();
            if(ValidateDateRange(start,end))
                ExportMTFDocument(start, end);
        }

        private bool ValidateDateRange(string start, string end)
        {
            //end date always after start date
            try
            {
                DateTime startDate = DateTime.Parse(start);
                DateTime endDate = DateTime.Parse(end);
                if(startDate > endDate)
                {
                    Message.Text = "<span id='messageLabel' style='color: red;'>Start Date cannot later than End Date.</span>";
                    return false;
                }
            }
            catch (Exception)
            {
                Message.Text = "<span id='messageLabel' style='color: red;'>Error on parsing Start Date and End Date. The Date format is incorrect.</span>";
                return false;
            }
            return true;
            //
        }

        private void ExportMTFDocument(string startDate, string endDate)
        {
            string filename = "Account Summary {0}-{1}.csv";

            filename = string.Format(filename, startDate.Replace("-", ""), endDate.Replace("-", ""));

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ContentType = "Application/x-msexcel";
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=\"" + filename + "\"");
            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);

            HttpContext.Current.Response.Write(GenerateCsv(startDate,endDate));
            HttpContext.Current.Response.End();

        }

        private string GenerateCsv(string startDate, string endDate)
        {
            SPWeb web = SPContext.Current.Web;
            SPList accountList = web.Lists[Common.ListAccounts];
            SPQuery query = new SPQuery();
            query.Query = BuildQueryString(startDate,endDate);
            query.QueryThrottleMode = SPQueryThrottleOption.Override;
            query.ViewAttributes = "Scope=\"Recursive\"";
            string result = string.Empty;
            SPSecurity.RunWithElevatedPrivileges(delegate()
                                                     {
                                    SPListItemCollection items = accountList.GetItems(query);
                                    result = GetCsvContent(web,items);
                                                     });

            return result;
        }

        private string GetCsvContent(SPWeb web,SPListItemCollection items)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Contract Date,Branch Code, MTF Number, Customer Name, Registration,Account Owner");

            foreach (SPListItem item in items)
            {
                string contractDate = Common.ConvertFieldToString(item[Common.FieldContractDate], FieldType.DateOnly);
                int branchId = Common.ConvertLookupFieldToId(item[Common.FieldFinanceOffice]);
                string branchCode = string.Empty;
                if(branchId != -1)
                    branchCode = Common.GetLookupOfficeCode(web, branchId);
                string mtfNum = Common.ConvertFieldToString(item[Common.FieldMTFNo], FieldType.Text);
                string customerName = string.Format("{0} {1}",
                                                    Common.ConvertFieldToString(item[Common.FieldFirstName],
                                                                                FieldType.Text),
                                                    Common.ConvertFieldToString(item[Common.FieldSurname],
                                                                                FieldType.Text));
                string reg = Common.ConvertFieldToString(item[Common.FieldRegNo], FieldType.Text);
                string owner = Common.ConvertFieldToString(item[Common.FieldAccountOwner], FieldType.User);
                sb.AppendLine(string.Format("{0},{1},{2},{3},{4},{5}", contractDate, branchCode, mtfNum, customerName,
                                            reg, owner));
            }

            return sb.ToString();
        }

        private bool ValidateWeb()
        {
            try
            {
                SPWeb web = SPContext.Current.Web;
                SPList accountList = web.Lists[Common.ListAccounts];
                if (accountList == null)
                    return false;
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        private string BuildQueryString(string startDate, string endDate)
        {
            string query = @"
                               <Where>
                                <And>
                                    <Neq><FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value></Neq>
                                  <And>
                                     <Geq>
                                        <FieldRef Name='{0}' />
                                        <Value IncludeTimeValue='TRUE' Type='DateOnly'>{1}</Value>
                                     </Geq>
                                     <Leq>
                                        <FieldRef Name='{0}' />
                                        <Value IncludeTimeValue='TRUE' Type='DateOnly'>{2}</Value>
                                     </Leq>
                                  </And>
                                </And>
                               </Where>
                            ";
            return string.Format(query, Common.FieldContractDate, startDate, endDate);
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            EnsureChildControls();

            writer.Write(@"<div style='float:left; padding: 20px;'>");
            startDateLabel.RenderControl(writer);
            startDate.RenderControl(writer);
            writer.Write("</div>");

            writer.Write(@"<div style='float:left; padding: 20px;'>");
            endDateLabel.RenderControl(writer);
            endDate.RenderControl(writer);
            writer.Write("</div>");

            writer.Write(@"<div style='margin: 0 auto; position:relative; padding: 20px; line-height: 20px;'>");
            btnExport.RenderControl(writer);
            writer.Write("</div>");

            writer.Write(@"<div style='float:left; width:100%; padding: 10px 20px; line-height:20px; font-size:12px;'>");
            Message.RenderControl(writer);
            writer.Write("</div>");
            
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }
    }
}
